﻿using System;

namespace Present.Commands.Async.Actions
{
    /// <summary>
    /// Delegate based async target
    /// </summary>
    public class DelegateAsyncAction<TParameter, TResult> : AsyncAction<TParameter, TResult>
    {
        private readonly Func<ActionExecution<TParameter>, TResult> doWork;
        private readonly Action<Exception> handleError;
        private readonly Action<TResult> handleSuccess;
        private readonly Func<TParameter, bool> canExecute;

        public DelegateAsyncAction(Func<ActionExecution<TParameter>, TResult> doWork, Action<Exception> handleError, Action<TResult> handleSuccess)
            : this(doWork, handleError, handleSuccess, x => true)
        {
        }

        public DelegateAsyncAction(Func<ActionExecution<TParameter>, TResult> doWork, Action<Exception> handleError, Action<TResult> handleSuccess, Func<TParameter, bool> canExecute)
        {
            this.doWork = doWork;
            this.handleError = handleError;
            this.handleSuccess = handleSuccess;
            this.canExecute = canExecute;
        }


        public override void HandleSuccess(TResult result)
        {
            handleSuccess(result);
        }

        public override TResult DoWork(ActionExecution<TParameter> execution)
        {
            return doWork(execution);
        }

        public override void HandleError(Exception error)
        {
            handleError(error);
        }


        public override bool CanExecute(object parameter)
        {
            return canExecute((TParameter)parameter);
        }

    }
}